home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir27 / calctool.zip / SUNVIEW.C < prev    next >
C/C++ Source or Header  |  1992-09-09  |  17KB  |  618 lines

  1.  
  2. /*  @(#)sunview.c 1.13 89/12/21
  3.  *
  4.  *  These are the SunView dependent graphics routines used by calctool.
  5.  *
  6.  *  Copyright (c) Rich Burridge.
  7.  *                Sun Microsystems, Australia - All rights reserved.
  8.  *
  9.  *  Permission is given to distribute these sources, as long as the
  10.  *  copyright messages are not removed, and no monies are exchanged.
  11.  *
  12.  *  No responsibility is taken for any errors or inaccuracies inherent
  13.  *  either to the comments or the code of this program, but if
  14.  *  reported to me then an attempt will be made to fix them.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <strings.h>
  19. #include "calctool.h"
  20. #include "color.h"
  21. #include "extern.h"
  22. #include <suntool/sunview.h>
  23. #include <suntool/canvas.h>
  24. #include <suntool/selection_svc.h>
  25. #include <suntool/selection_attributes.h>
  26.  
  27. #define  ICON_SET                       (void) icon_set
  28. #define  MENU_SET                       (void) menu_set
  29. #define  NOTIFY_INTERPOSE_DESTROY_FUNC  (void) notify_interpose_destroy_func
  30. #define  PW_SETCMSNAME                  (void) pw_setcmsname
  31. #define  PW_PUTCOLORMAP                 (void) pw_putcolormap
  32. #define  PW_REVERSEVIDEO                (void) pw_reversevideo
  33. #define  PW_TTEXT                       (void) pw_ttext
  34. #define  PW_VECTOR                      (void) pw_vector
  35. #define  PW_WRITEBACKGROUND             (void) pw_writebackground
  36. #define  SELN_QUERY                     (void) seln_query
  37. #define  WINDOW_DONE                    (void) window_done
  38. #define  WINDOW_SET                     (void) window_set
  39.  
  40. #define  SMALLFONT   "/usr/lib/fonts/fixedwidthfonts/screen.r.7"
  41. #define  NORMALFONT  "/usr/lib/fonts/fixedwidthfonts/screen.b.14"
  42. #define  BIGFONT     "/usr/lib/fonts/fixedwidthfonts/gallant.r.19"
  43.  
  44. void func_key_proc() ;
  45.  
  46. Canvas kcanvas, rcanvas ;
  47. Cursor help_cursor, main_cursor ;
  48. Event *cur_event ;
  49. Frame frame, rframe ;
  50. Icon calctool_icon ;
  51. Menu menus[MAXMENUS] ;
  52. Notify_value destroy_proc() ;
  53. Pixfont *font, *sfont, *nfont, *bfont ;
  54. Pixwin *pw, *cpw, *rcpw ;
  55. Seln_client sel_client ;
  56. Seln_holder holder ;
  57. Seln_rank rank = SELN_PRIMARY ;
  58. Seln_result get_proc(), reply_proc() ;
  59.  
  60. short help_cursor_array[16] = {
  61. #include "help.cursor"
  62. } ;
  63. mpr_static(help_cursor_pr, 16, 16, 1, help_cursor_array) ;
  64.  
  65. unsigned short icon_image[] = {
  66. #include "calctool.icon"
  67. } ;
  68. mpr_static(icon_pr, 64, 64, 1, icon_image) ;
  69.  
  70. short cicon_image[] = {
  71. #include "calctool.color.icon"
  72. } ;
  73. mpr_static(cicon_pr, 64, 64, 8, cicon_image) ;
  74.  
  75.  
  76. /*ARGSUSED*/
  77. void
  78. canvas_proc(canvas, event, arg)
  79. Canvas canvas ;
  80. Event *event ;
  81. caddr_t arg ;
  82. {
  83.   cur_event = event ;
  84.   process_event(get_next_event(event)) ;
  85. }
  86.  
  87.  
  88. clear_canvas(window, color)
  89. enum can_type window ;
  90. int color ;
  91. {
  92.   int height, width ;
  93.   Canvas ctype ;
  94.  
  95.   if (window == KEYCANVAS)
  96.     {
  97.       pw = cpw ;
  98.       ctype = frame ;
  99.     }
  100.   else if (window == REGCANVAS)
  101.     {
  102.       pw = rcpw ;
  103.       ctype = rframe ;
  104.     }
  105.   height = (int) window_get(ctype, WIN_HEIGHT) ;
  106.   width = (int) window_get(ctype, WIN_WIDTH) ;
  107.   PW_WRITEBACKGROUND(pw, 0, 0, width, height, PIX_SRC | PIX_COLOR(color)) ;
  108. }
  109.  
  110.  
  111. close_frame()
  112. {
  113.   if ((int) window_get(rframe, WIN_SHOW) == TRUE)
  114.     WINDOW_SET(rframe, WIN_SHOW, FALSE, 0) ;
  115.   WINDOW_SET(frame, FRAME_CLOSED, TRUE, 0) ;
  116.   rstate = 0 ;
  117. }
  118.  
  119.  
  120. color_area(x, y, width, height, color)
  121. int x, y, width, height, color ;
  122. {
  123.   PW_WRITEBACKGROUND(cpw, x, y, width, height, PIX_SRC | PIX_COLOR(color)) ;
  124. }
  125.  
  126.  
  127. create_menu(mtype)       /* Create popup menu for right button press. */
  128. enum menu_type mtype ;
  129. {
  130.   int i ;
  131.  
  132.   menus[(int) mtype] = menu_create(MENU_FONT, nfont, 0) ;
  133.   for (i = 0; i < MAXREGS; i++)
  134.     {
  135.       switch (mtype)
  136.         {
  137.           case M_ACC    :                              /* Accuracies. */
  138.           case M_EXCH   :                              /* Register exchange. */
  139.           case M_LSHIFT :                              /* Left shift. */
  140.           case M_RCL    :                              /* Register recall. */
  141.           case M_RSHIFT :                              /* Right shift. */
  142.           case M_STO    : MENU_SET(menus[(int) mtype], /* Register store. */
  143.                                    MENU_STRING_ITEM, num_names[i], i+1, 0) ;
  144.                           break ;
  145.           case M_CON    : if (strlen(con_names[i]))    /* Constants. */
  146.                             MENU_SET(menus[(int) mtype],
  147.                                      MENU_STRING_ITEM, con_names[i], i+1, 0) ;
  148.                           break ;
  149.           case M_FUN    : if (strlen(fun_names[i]))    /* Functions. */
  150.                             MENU_SET(menus[(int) mtype],
  151.                                      MENU_STRING_ITEM, fun_names[i], i+1, 0) ;
  152.         }
  153.     }
  154. }
  155.  
  156.  
  157. destroy_frame()
  158. {
  159.   WINDOW_DONE(frame) ;
  160.   exit(0) ;
  161. }
  162.  
  163.  
  164. destroy_rframe(frame)
  165. Frame frame ;
  166. {
  167.   rstate = 0 ;
  168.   WINDOW_SET(frame, WIN_SHOW, FALSE, 0) ;
  169. }
  170.  
  171.  
  172. /*ARGSUSED*/
  173. Notify_value
  174. destroy_proc(client, status)
  175. Notify_client client ;
  176. Destroy_status status ;
  177. {
  178.   exit(0) ;
  179. }
  180.  
  181.  
  182. do_menu(mtype)          /* Popup appropriate menu and get value. */
  183. enum menu_type mtype ;
  184. {
  185.   return ((int) menu_show(menus[(int) mtype], kcanvas,
  186.                           canvas_window_event(kcanvas, cur_event), 0)) ;
  187. }
  188.  
  189.  
  190. drawline(x1, y1, x2, y2)
  191. int x1, y1, x2, y2 ;
  192. {
  193.   PW_VECTOR(cpw, x1, y1, x2, y2, PIX_SET, 0) ;
  194. }
  195.  
  196.  
  197. draw_regs()
  198. {
  199.   make_registers() ;
  200.   WINDOW_SET(rframe, WIN_SHOW, TRUE, 0) ;
  201. }
  202.  
  203.  
  204. drawtext(x, y, window, fontno, color, str)
  205. enum font_type fontno ;
  206. enum can_type window ;
  207. int x, y, color ;
  208. char *str ;
  209. {
  210.        if (fontno == SFONT) font = sfont ;
  211.   else if (fontno == NFONT) font = nfont ;
  212.   else if (fontno == BFONT) font = bfont ;
  213.        if (window == KEYCANVAS) pw = cpw ;
  214.   else if (window == REGCANVAS) pw = rcpw ;
  215.   PW_TTEXT(pw, x, y, PIX_SRC | PIX_COLOR(color), font, str) ;
  216. }
  217.  
  218.  
  219. /*ARGSUSED*/
  220. void
  221. func_key_proc(client_data, args)
  222. char *client_data ;
  223. Seln_function_buffer *args ;
  224. {
  225.   get_display() ;
  226. }
  227.  
  228.  
  229. get_display()     /* The GET function key has been pressed. */
  230. {
  231.   if (seln_acquire(sel_client, SELN_SHELF) == SELN_SHELF)
  232.     {
  233.       if (shelf != NULL) free(shelf) ;
  234.       shelf = malloc((unsigned) strlen(display)) ;
  235.       STRCPY(shelf, display) ;         /* Safely keep copy of display. */
  236.     }
  237. }
  238.  
  239.  
  240. Pixfont *
  241. get_font(name)
  242. char *name ;
  243. {
  244.   Pixfont *font ;
  245.  
  246.   font = pf_open(name) ;
  247.   if (font == NULL) font = pf_default() ;
  248.   if (font == NULL)
  249.     {
  250.       perror("couldn't get the default font.") ;
  251.       exit(1) ;
  252.     }
  253.   return font ;
  254. }
  255.  
  256.  
  257. get_next_event(event)
  258. Event *event ;
  259. {
  260.   static char eb[4] ;      /* Event buffer. */
  261.   int i ;
  262.  
  263. #ifdef   SUN4_KEYBOARD
  264.   char *rpad = "\000\000\000=/*789456123" ;
  265.   char *akeys = "8264" ;
  266.   char *sun4keys = "\015\000\000+-\000\0000\000." ;
  267. #else
  268.   char *rpad = "*-+7894561230.=" ;
  269.   char *akeys = "5.31" ;
  270. #endif /*SUN4_KEYBOARD*/
  271.  
  272.   nextc = event_id(event) ;
  273.   curx = event_x(event) ;
  274.   cury = event_y(event) ;
  275.  
  276.   if (event_is_button(event))
  277.          if (event_is_down(event) && nextc == MS_LEFT) return(LEFT_DOWN) ;
  278.     else if (event_is_down(event) && nextc == MS_MIDDLE) return(MIDDLE_DOWN) ;
  279.     else if (event_is_down(event) && nextc == MS_RIGHT) return(RIGHT_DOWN) ;
  280.     else if (event_is_up(event) && nextc == MS_LEFT) return(LEFT_UP) ;
  281.     else if (event_is_up(event) && nextc == MS_MIDDLE) return(MIDDLE_UP) ;
  282.     else if (event_is_up(event) && nextc == MS_RIGHT) return(RIGHT_UP) ;
  283.  
  284. /*  The following code attempts to handle a numeric keypad using the right
  285.  *  function keys. This pad differs on the Sun3 and Sun4 keyboards. There
  286.  *  is a compile-time define which determines which keyboard setup is
  287.  *  looked for.
  288.  */
  289.  
  290.   if (event_is_ascii(event))
  291.     {
  292.  
  293. /*  If the last two events were escape and left square bracket.. */
  294.  
  295.       if (eb[0] && eb[1])
  296.         {
  297.           switch (nextc)
  298.             {
  299.  
  300. /*  Interpret the arrow keys (if they are set).
  301.  *  R8 = ^[A     R14 = ^[B     R12 = ^[C     R10 = ^[B
  302.  */
  303.  
  304.               case 'A' :
  305.               case 'B' :
  306.               case 'C' :
  307.               case 'D' : cur_ch = akeys[nextc - 'A'] ;
  308.                          eb[0] = eb[1] = '\0' ;
  309.                          return(KEYBOARD) ;
  310.  
  311. /*  Interpret the extra keys found on Sun4 keyboards.
  312.  *  These have codes of the form: ^[<int>z where <int> is a number
  313.  *  between 247 and 255.  We're only interested in 5 of these keys.
  314.  *  These are:
  315.  *    ^[253z = +  ^[254z = -  ^[247z = 0  ^[249z = .  ^[250z = Enter
  316.  */
  317. #ifdef SUN4_KEYBOARD
  318.               case '2' : eb[2] = '2' ;
  319.                          break ;
  320.  
  321.               case '5' : if (eb[0] && eb[1] && eb[2])
  322.                            {
  323.                              eb[3] = '5' ;
  324.                              break ;
  325.                            }
  326.                          else 
  327.  
  328. /*  Clear event_buf and treat as normal ascii char. */
  329.  
  330.                            {
  331.                              eb[0] = eb[1] = '\0' ;
  332.                              cur_ch = nextc ;
  333.                              return(KEYBOARD) ;
  334.                            }
  335.  
  336.               case '0' :
  337.               case '3' :
  338.               case '4' :
  339.               case '7' :
  340.               case '9' : if (eb[0] && eb[1] && eb[2] && eb[3])
  341.                            {
  342.                              cur_ch = sun4keys[nextc - '0'] ;
  343.                              eb[0] = eb[1] = eb[2] = eb[3] = '\0' ;
  344.                              return(KEYBOARD) ;
  345.                            }
  346.                          else if (eb[0] && eb[1] && eb[2] && nextc == '4')
  347.                            {
  348.                              eb[3] = nextc ;
  349.                              break ;
  350.                            }
  351.                          else
  352.  
  353. /*  Clear event_buf and treat as normal ascii char. */
  354.  
  355.                            {
  356.                              eb[0] = eb[1] = '\0' ;
  357.                              cur_ch = nextc ;
  358.                              return(KEYBOARD) ;
  359.                            }
  360. #endif /*SUN4_KEYBOARD*/
  361.  
  362.                default : eb[0] = eb[1] = eb[2] = eb[3] = '\0' ;
  363.             }
  364.         }
  365.  
  366. /*  If previous events are ^[[ : set buffer   */
  367.  
  368.       else if (nextc == '[' && eb[0])    /* Check for left square bracket. */
  369.         eb[1] = '[' ;
  370.       else if (nextc == '\033')          /* Check for escape char. */
  371.         eb[0] = '\033' ;
  372.       else 
  373.         {
  374.  
  375. /*  All the rest of the ASCII characters. */
  376.  
  377.           eb[0] = eb[1] = '\0' ;
  378.           cur_ch = nextc ;
  379.           return(KEYBOARD) ;
  380.         }
  381.     }
  382.  
  383.   if (event_is_key_right(event) && event_is_up(event))
  384.     {
  385.       for (i = 1; i < 16; i++)
  386.         if (nextc == KEY_RIGHT(i))
  387.           {
  388.             cur_ch = rpad[i-1] ;
  389.             return(KEYBOARD) ;
  390.           }
  391.     }
  392.   if (nextc == KBD_DONE && down) return(EXIT_WINDOW) ;
  393.   if (nextc == LOC_WINEXIT || nextc == LOC_RGNEXIT) return(EXIT_WINDOW) ;
  394.   if (nextc == LOC_WINENTER || nextc == LOC_RGNENTER) return(ENTER_WINDOW) ;
  395.   if (nextc == WIN_REPAINT) return(CFRAME_REPAINT) ;
  396.   if ((nextc == KEY_LEFT(6)) & event_is_up(event)) return(PUT_ON_SHELF) ;
  397.   if ((nextc == KEY_LEFT(8)) && event_is_up(event)) return(TAKE_FROM_SHELF) ;
  398.   return(LASTEVENTPLUSONE) ;
  399. }
  400.  
  401.  
  402. Seln_result
  403. get_proc(buffer)
  404. Seln_request *buffer ;
  405. {
  406.   issel = 0 ;
  407.   if (*buffer->requester.context == 0)
  408.     {
  409.       if (buffer == (Seln_request *) NULL ||
  410.           *((Seln_attribute *) buffer->data) != SELN_REQ_CONTENTS_ASCII)
  411.         return ;
  412.       selection = buffer->data + sizeof(Seln_attribute) ;
  413.       *buffer->requester.context = 1 ;
  414.     }
  415.   else selection = buffer->data ;
  416.   issel = 1 ;
  417. }
  418.  
  419.  
  420. handle_selection()  /* Handle the GET function key being pressed. */
  421. {
  422.   char context = 0 ;
  423.  
  424.   holder = seln_inquire(rank) ;
  425.   if (holder.state == SELN_NONE) return ;
  426.   SELN_QUERY(&holder, get_proc, &context, SELN_REQ_CONTENTS_ASCII, 0, 0) ;
  427. }
  428.  
  429.  
  430. init_fonts()
  431. {
  432.   bfont = get_font(BIGFONT) ;
  433.   nfont = get_font(NORMALFONT) ;
  434.   nfont_width = nfont->pf_defaultsize.x ;
  435.   sfont = get_font(SMALLFONT) ;
  436. }
  437.  
  438.  
  439. init_ws_type()
  440. {
  441.   if (getenv("WINDOW_PARENT") == NULL)
  442.     {
  443.       FPRINTF(stderr,"%s: Not a native SunView window\n", progname) ;
  444.       return -1 ;
  445.     }
  446.   gtype = SVIEW ;
  447.   return 0 ;
  448. }
  449.  
  450.  
  451. load_colors()      /* Create and load calctool color map. */
  452. {
  453.   Pixwin *frame_pw ;
  454.   char colorname[CMS_NAMESIZE] ;
  455.   u_char red[CALC_COLORSIZE], green[CALC_COLORSIZE], blue[CALC_COLORSIZE] ;
  456.  
  457.   iscolor = (cpw->pw_pixrect->pr_depth == 8) ? 1 : 0 ;
  458.   SPRINTF(colorname, "%s%D", CALC_COLOR, getpid()) ;
  459.   PW_SETCMSNAME(cpw, colorname) ;
  460.  
  461.   calc_colorsetup(red, green, blue) ;
  462.   PW_PUTCOLORMAP(cpw, 0, CALC_COLORSIZE, red, green, blue) ;
  463.   if (inv_video) PW_REVERSEVIDEO(cpw, 0, CALC_COLORSIZE) ;
  464.  
  465.   if (iscolor)
  466.     {
  467.       frame_pw = (Pixwin *) window_get(frame, WIN_PIXWIN, 0) ;
  468.       PW_SETCMSNAME(frame_pw, colorname) ;
  469.       PW_PUTCOLORMAP(frame_pw, 0, CALC_COLORSIZE, red, green, blue) ;
  470.     }
  471. }
  472.  
  473.  
  474. make_frames(argc, argv)
  475. int argc ;
  476. char *argv[] ;
  477. {
  478.   frame = window_create((Window) 0, FRAME,
  479.                         FRAME_ICON,       calctool_icon,
  480.                         FRAME_SHOW_LABEL, FALSE,
  481.                         FRAME_NO_CONFIRM, TRUE,
  482.                         FRAME_ARGS,       argc, argv,
  483.                         0) ;
  484.   sel_client = seln_create(func_key_proc, reply_proc, (char *) 0) ;
  485.   NOTIFY_INTERPOSE_DESTROY_FUNC(frame, destroy_proc) ;
  486.   rframe = window_create(frame, FRAME,
  487.                          FRAME_SHOW_LABEL, FALSE,
  488.                          FRAME_NO_CONFIRM, TRUE,
  489.                          FRAME_DONE_PROC,  destroy_rframe,
  490.                          WIN_X,            TWIDTH+15,
  491.                          WIN_Y,            0,
  492.                          WIN_SHOW,         FALSE,
  493.                          WIN_WIDTH,        TWIDTH,
  494.                          WIN_HEIGHT,       200,
  495.                          WIN_FONT,         nfont,
  496.                          0) ;
  497.  
  498. }
  499.  
  500.  
  501. make_icon()
  502. {
  503.   calctool_icon = icon_create(ICON_WIDTH, ICONWIDTH,
  504.                               ICON_IMAGE, &icon_pr,
  505.                               0) ;
  506. }
  507.  
  508.  
  509. make_items()
  510. {
  511.   main_cursor = window_get(kcanvas, WIN_CURSOR) ;
  512.  
  513.   if (iscolor)
  514.     {
  515.       calctool_icon = (Icon) window_get(frame, FRAME_ICON) ;
  516.       ICON_SET(calctool_icon, ICON_IMAGE, &cicon_pr, 0) ;
  517.       WINDOW_SET(frame, FRAME_ICON, calctool_icon, 0) ;
  518.     }
  519.  
  520.   help_cursor = cursor_create(CURSOR_XHOT,  0,
  521.                               CURSOR_YHOT,  0,
  522.                               CURSOR_OP,    PIX_SRC | PIX_DST,
  523.                               CURSOR_IMAGE, &help_cursor_pr, 0) ;
  524.   window_fit(frame) ;
  525. }
  526.  
  527.  
  528. make_subframes()
  529. {
  530.   rcanvas = window_create(rframe, CANVAS, 0) ;
  531.   kcanvas = window_create(frame, CANVAS,
  532.                           CANVAS_RETAINED,     FALSE,
  533.                           WIN_EVENT_PROC,      canvas_proc,
  534.                           WIN_WIDTH,           TWIDTH,
  535.                           WIN_HEIGHT,          THEIGHT + DISPLAY,
  536.                           WIN_FONT,            nfont,
  537.                           0) ;
  538.  
  539.   WINDOW_SET(kcanvas, WIN_CONSUME_KBD_EVENTS, WIN_ASCII_EVENTS,
  540.                       WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS,
  541.                       WIN_UP_EVENTS, 0, 0) ;
  542.   WINDOW_SET(kcanvas, WIN_IGNORE_PICK_EVENT, LOC_MOVE, 0) ;
  543.   cpw = canvas_pixwin(kcanvas) ;
  544.   rcpw = canvas_pixwin(rcanvas) ;
  545. }
  546.  
  547.  
  548. /*ARGSUSED*/
  549. Seln_result
  550. reply_proc(item, context, length)
  551. Seln_attribute item ;
  552. Seln_replier_data *context ;
  553. int length ;
  554. {
  555.   int size ;
  556.   char *destp ;
  557.  
  558.   switch (item)
  559.     {
  560.       case SELN_REQ_CONTENTS_ASCII :
  561.  
  562.              if (context->context == NULL)
  563.                {
  564.                  if (shelf == NULL) return(SELN_DIDNT_HAVE) ;
  565.                  context->context = shelf ;
  566.                }
  567.              size = strlen(context->context) ;
  568.              destp = (char *) context->response_pointer ;
  569.              STRCPY(destp, context->context) ;
  570.              destp += size ;
  571.              while ((int) destp % 4 != 0) *destp++ = '\0' ;
  572.              context->response_pointer = (char **) destp ;
  573.              *context->response_pointer++ = 0 ;
  574.              return(SELN_SUCCESS) ;
  575.  
  576.       case SELN_REQ_YIELD :
  577.  
  578.              *context->response_pointer++ = (char *) SELN_SUCCESS ;
  579.              return(SELN_SUCCESS) ;
  580.  
  581.       case SELN_REQ_BYTESIZE :
  582.  
  583.              if (shelf == NULL) return(SELN_DIDNT_HAVE) ;
  584.              *context->response_pointer++ = (char *) strlen(shelf) ;
  585.              return(SELN_SUCCESS) ;
  586.  
  587.       case SELN_REQ_END_REQUEST : return(SELN_SUCCESS) ;
  588.  
  589.       default                   : return(SELN_UNRECOGNIZED) ;
  590.     }
  591. }
  592.  
  593.  
  594. set_cursor(type)
  595. int type ;
  596. {
  597.   switch (type)
  598.     {
  599.       case HELPCURSOR : WINDOW_SET(kcanvas, WIN_CURSOR, help_cursor, 0) ;
  600.                         break ;
  601.       case MAINCURSOR : WINDOW_SET(kcanvas, WIN_CURSOR, main_cursor, 0) ;
  602.     }
  603. }
  604.  
  605.  
  606. start_tool()
  607. {
  608.   window_main_loop(frame) ;
  609. }
  610.  
  611.  
  612. toggle_reg_canvas()
  613. {
  614.   rstate = !rstate ;
  615.   if (rstate) draw_regs() ;
  616.   else WINDOW_SET(rframe, WIN_SHOW, FALSE, 0) ;
  617. }
  618.